Improve taylor series calculation of exp and sin by binary splitting method #433
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
With #407,
exp(x, N)
andsin(x, N)
calculation improves fromO(N^3/logN)
toO(N^2)
.This pull request further improves
O(N^2)
toO(N*(logN)**a)
where a is about 3 or 4.Drops Ruby 2.5 support to use
(1..).bsearch
Binary Splitting method
If
x
can be represented assmall_numerator/small_denominator
,exp(x)
andsin(x)
can be calculated fast using binary splitting method.This technique is normally used in PI calculation.
Here's an example of calculating
exp(1)
.The prerequisite is that all numbers are small in the initial step.
In each step, average number of digits doubles and number of terms halves.
Split digits (decimal form of bit-burst algorithm)
Normally,
x
has many digits, so simply applying binary splitting method toexp(x)
isn't fast.Now lets split
x
into several parts.Number of digits doubled, number of terms required for convergence is almost halved.
So each
exp
calculation performs well with binary splitting method.We need to repeat binary splitting method for about
logN
times, so the total time complexity will be quasilinear time.BigMath.sin
Almost the same as
BigMath.exp
.Restore
sin(x.xxxxxxxxxxxxxxxx)
fromsin(x.xx)
,sin(0.00xx)
,sin(0.0000xxxx)
,sin(0.00000000xxxxxxxx)
using trigonometric addition theorem.BigMath.log and BigMath.atan
Since
exp
andsin
becomes orders of magnitude faster, implementinglog
andatan
by newton's method is better.log(x)
: Solveexp(y) - x = 0
atan(x)
: Solvetan(y) - x = 0
There is an option to implement binary splitting method to
log
andatan
taylor series, but implementation will be more complicated, needs special care to make|x| ≪ 1
, and convergence is slower thanexp
andsin
.